Fix verbose handling in OptimizationMOI#1235
Merged
ChrisRackauckas merged 2 commits intoJun 25, 2026
Merged
Conversation
`__map_optimizer_args` read `cache.verbose`, but the MOI caches (`MOIOptimizationNLPCache`/`MOIOptimizationCache`) store solve kwargs in `solver_args` and have no `verbose` field, so passing `verbose` together with a common tolerance threw `FieldError: type MOIOptimizationNLPCache has no field verbose`. Separately, `verbose` was splatted from `solver_args` into the raw optimizer-attribute loop, so a plain `verbose=`-solve failed with `Unable to add option "verbose"`. Consume `verbose` as a named keyword of `__map_optimizer_args` (so it is no longer forwarded as a raw solver attribute) and run it through `_process_verbose_param` for the `@SciMLMessage` calls. Both manifestations surface through the BoundaryValueDiffEq optimization-based BVP path, which passes `abstol` and an `OptimizationVerbosity` to the optimizer. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RtJAi7bALH5XkakjS6Yb6j
Two pre-existing Aqua failures in the OptimizationMOI QA suite: - Declare the SciMLBase solver-trait methods defined on the MathOptInterface optimizer types (`__init`, `allowsbounds`, `requiresgradient`, ...) as allowed via `piracies = (treat_as_own = [...],)`. These are an intentional interface extension, not piracy. - Add the missing `[compat]` bound for `ReverseDiff` (a test-only `[extras]` dependency), which Aqua's deps_compat check requires. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RtJAi7bALH5XkakjS6Yb6j
Contributor
Author
|
Pushed two follow-up commits addressing the OptimizationMOI QA (Aqua) failures, which are pre-existing on
The third QA finding (a JET error on Should be ignored until reviewed by @ChrisRackauckas. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes a crash when
verboseis passed to a MOI optimizer through OptimizationMOI. There are two manifestations, both from the same root cause —__map_optimizer_argswas never updated for theOptimizationVerbositysystem, whileverboseflows into the cache'ssolver_args:FieldError: type MOIOptimizationNLPCache has no field verbose— the@SciMLMessagecalls readcache.verbose, but the MOI caches (MOIOptimizationNLPCache/MOIOptimizationCache) keep solve kwargs insolver_argsand have noverbosefield. Triggered whenever a common tolerance (abstol/reltol/maxiters) is passed alongsideverbose.Unable to add option "verbose" ... must be ::String, ::Integer, or ::Float64—verbosewas splatted fromsolver_argsinto the raw optimizer-attribute loop, so even a plainverbose=-solve (no tolerance) failed by trying to setverboseas an IpoptRawOptimizerAttribute.Fix
__map_optimizer_argsnow consumesverboseas a named keyword (so it is no longer forwarded into the raw-attribute loop) and runs it throughOptimizationBase._process_verbose_paramto obtain a validOptimizationVerbosityfor the@SciMLMessagecalls. The now-unusedcacheargument is dropped and both call sites updated.How it surfaced
Reported via the BoundaryValueDiffEq optimization-based BVP path (the rocket optimal-control example), which builds an
OptimizationProblemand callssolve(prob, Ipopt.Optimizer(); abstol=..., verbose=OptimizationVerbosity())— hitting manifestation (1).Testing
@testset "verbose kwarg"covering all three cases (verbose-only, verbose+abstol,verbose=true). Each reproduces a pre-fix failure and passes after.OptimizationMOICore suite run locally on Julia 1.12.6 — all green (the 2Brokenincacheare pre-existing@test_broken):MIRK4(; optimize = Ipopt.Optimizer())) now returnsretcode = Success(max height1.0128323), matching the OptimizationIpopt result.This PR is a draft and should be ignored until reviewed by @ChrisRackauckas.
🤖 Generated with Claude Code
https://claude.ai/code/session_01RtJAi7bALH5XkakjS6Yb6j